package com.warski.wonderfires.net;

import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import com.warski.wonderfires.TheApplication;
import com.warski.wonderfires.dlna.DLNAManager;
import com.warski.wonderfires.dlna.params.SettingsConstants;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

import static com.warski.wonderfires.TheApplication.mContext;

/**
 * tcp 连接类
 */

public class TCPConn {
    private TCPConn() {
    }

    private static TCPConn _instance = null;

    public static TCPConn getInstance() {
        if (_instance == null)
            _instance = new TCPConn();
        return _instance;
    }

    private static final String Tag = "TCPConn";
    private final static int TASK_SEND_DATA = 2;
    private final static int KILL_TASK = 3; //退出loop

    private String dstAddr;
    private int dstPort;
    private Handler mWorker = null;

    Socket dataSocket = null;
    Thread thRcv = null;
    boolean isRunFlg = true;
    Object objLock = new Object();
    int timeout = 1500;
    String lastErrCmd = "";
    int tryCount = 3;
    public boolean tryNetAddr(String dstAddr, int dstPort, int timeout) {
        this.dstAddr = dstAddr;
        this.dstPort = dstPort;
        this.timeout = timeout;
        return tryConn(timeout);
    }

    private boolean tryConn(int timeout) {
        Log.i(Tag, "makeText tryConn: tryConn");
        if (mWorker != null) {
            mWorker.getLooper().quit();
            mWorker = null;
        }
        if (dataSocket != null) {
            try {
                dataSocket.close();
            } catch (Exception ex) {
            }
            dataSocket = null;
        }
        if (thRcv != null) {
            try {
                thRcv.interrupt();
            } catch (Exception ex) {
            }
            thRcv = null;
        }

        try {
            InetAddress ipAddress = InetAddress.getByName(dstAddr);
            dataSocket = new Socket(ipAddress,dstPort);
            dataSocket.setKeepAlive(true);

            isRunFlg = true;
            TheApplication.getInstance().settingsPut(SettingsConstants.PREF_SETTINGS_IP,dstAddr);
            TheApplication.isConnection = true;
            //开启消息接收线程
            thRcv = new Thread(rcvMessages);
            thRcv.start();
            HandlerThread ht = new HandlerThread(Tag);
            ht.start();
            if (mWorker == null) mWorker = new Handler(ht.getLooper(), cbSendBg);
            mWorker.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (!DLNAManager.isPlaying()) sendData(JsonStep.DeviceStatus.getJsonString());
                    mWorker.postDelayed(this,5000);
                }
            },5000);
            if (!TextUtils.isEmpty(lastErrCmd)) {
                sendData(lastErrCmd);
            }
        } catch (Exception ex) {
            try {
                Thread.sleep(200);
            } catch (Exception x) {
            }
            TheApplication.isConnection = false;
            Log.i(Tag, "errMsg:" + ex.getMessage());
            ex.printStackTrace();
            tryCount--;
            if (tryCount > 0) {
                new Thread(() -> {
                    tryConn(timeout);
                }).start();
            }else {
                close();
            }
        }
        return true;
    }

    public void close() {
        TheApplication.isConnection = false;
        if (mWorker != null) {
            mWorker.sendEmptyMessage(KILL_TASK);
        }
        isRunFlg = false;

        if (thRcv != null) {
            try {
                thRcv.interrupt();
            } catch (Exception ex) {
            }
            thRcv = null;
        }
        if (dataSocket != null) {
            try {
                dataSocket.close();
            } catch (Exception ex) {
            }
            dataSocket = null;
        }
        Intent intent = new Intent("tcpClose");
        intent.putExtra("tcpClose", "tcpClose");
        mContext.sendBroadcast(intent);
    }

    Runnable rcvMessages = new Runnable() {
        @Override
        public void run() {
            while (isRunFlg && dataSocket != null && dataSocket.isConnected()) {
                try {
                    // 数据解析
                    InputStream mInputStream = dataSocket.getInputStream();
                    if (mInputStream.available() <= 0) {
                        continue;
                    } else {
                        Thread.sleep(300);
                    }
                    byte[] buffer = new byte[120];
                    int size = mInputStream.read(buffer);
                    byte[] readBytes = new byte[size];
                    System.arraycopy(buffer, 0, readBytes, 0, size);
                    String value = new String(readBytes);
                    Log.i(Tag,"手机收到的"+dstAddr+"数据: " + value);

                    if (value.contains("fire_status")){
                        String status = value.split("fire_status")[1].trim().split(":")[1].trim();
                        Log.d(Tag,"fire_status--->" + status.substring(1,2));
                        if (status.substring(1,2).equals("k")) {
                            Intent intent = new Intent("gearsData");
                            intent.putExtra("gearsData", "0");
                            mContext.sendBroadcast(intent);
                        }else if (value.contains("fire_level")){
                            String gears = value.split("fire_level")[1].trim().split(":")[1].trim();
                            Log.d(Tag,"gears--->" + gears.substring(1,2));

                            Intent intent = new Intent("gearsData");
                            intent.putExtra("gearsData", gears.substring(1,2));
                            mContext.sendBroadcast(intent);
                        }
                    }

                } catch (Exception e) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    e.printStackTrace();
                }
            }
        }
    };

    private Handler.Callback cbSendBg = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case TASK_SEND_DATA: {
                    synchronized (objLock) {
                        if (msg.obj != null) {
                            String json = msg.obj.toString();
                            if (!TextUtils.isEmpty(json)) {
                                Log.i(Tag, "send data:" + json);
                                try {
                                    OutputStream output = dataSocket.getOutputStream();
                                    output.write((json + "\n").getBytes());
                                    output.flush();
                                    tryCount = 3;
                                } catch (Exception ex) {
                                    lastErrCmd = json;
                                    Log.i(Tag, "err:" + ex.getMessage());
                                    ex.printStackTrace();
                                    tryThree();
                                }
                            }
                        }
                    }
                    break;
                }
                case KILL_TASK:
                    mWorker.getLooper().quit();
                    mWorker.removeCallbacksAndMessages(null);
                    mWorker = null;
                    break;
            }
            return true;
        }
    };

    public void sendData(String json) {

        if (mWorker != null) {
            Message msg = Message.obtain();
            msg.what = TASK_SEND_DATA;
            msg.obj = json;
            mWorker.sendMessage(msg);
            Log.e(Tag,"sendData 发送的消息="+json);
        }
    }

    private void tryThree() {
        tryCount = 3;
        if (!isConnectInternet(TheApplication.getInstance()))
            return;
        while (tryCount >= 0) {
            try {
                Thread.sleep(50);
            } catch (Exception ex) {
            }
            try {
                OutputStream output = dataSocket.getOutputStream();
                output.write((lastErrCmd + "\n").getBytes());
                output.flush();
                output.close();
                tryCount = 3;
                return;
            } catch (Exception ex) {
                tryCount--;
                if (tryCount < 0) {
                    Log.i(Tag, "网络连接断开！！");
                    close();
                    return;
                }
                Log.i(Tag, "err:" + ex.getMessage());
            }
        }
    }
    public boolean isConnectInternet(Context context) {
        ConnectivityManager conManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (conManager != null) {
            try {
                NetworkInfo networkInfo = conManager.getActiveNetworkInfo();
                if (networkInfo != null) {
                    return networkInfo.isAvailable();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        TheApplication.isConnection = false;
        return false;
    }
}
